package com.jron.cqiu.kernel.implement.crossos.jnative;

import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.util.PsAPI;
import org.xvolks.jnative.util.Kernel32;
import org.xvolks.jnative.misc.basicStructures.HANDLE;
import org.xvolks.jnative.pointers.Pointer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.jron.cqiu.kernel.process.IProcess;

/**
 * Created by Intellij IDEA.
 *
 * @Author: Yejw
 * @Date: 2008-6-12
 * @Time: 21:29:23
 */
public class JNativeProcess implements IProcess {

    private static Log log = LogFactory.getLog(JNativeProcess.class);

    /**
     * 结束进程
     *
     * @param moduleBaseName
     * @param ignoreCase     映像名称是否忽略大小写
     * @return
     */
    public int kill(String moduleBaseName, boolean ignoreCase) {
        JNativeInit.instance().init();

        int ret = 0;
        try {
            int[] pids = PsAPI.EnumProcess(1024);
            ret = 2;
            log.debug("Nombre de process " + pids.length);

            for (int i = pids.length; i > 0;) {
                int pid = pids[--i];
                HANDLE lHandle = Kernel32.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION
                        | Kernel32.PROCESS_VM_READ, false, pid);
                log.debug("pid=" + pid + ", handle=" + (lHandle == null ? "null" : lHandle.getValue()));

                if (lHandle != null) {
                    Pointer hModuleEtoile = PsAPI.EnumProcessModules(lHandle, 1024);
                    if (hModuleEtoile.getPointer() > 0
                            && (ignoreCase ? moduleBaseName.equalsIgnoreCase(PsAPI.GetModuleBaseName(lHandle,
                            hModuleEtoile.getAsInt(0), 1024)) : moduleBaseName.equals(PsAPI.GetModuleBaseName(lHandle,
                            hModuleEtoile.getAsInt(0), 1024)))) {

                        log.debug("Found the dest module base: " + moduleBaseName);
                        HANDLE llHandle = Kernel32.OpenProcess(Kernel32.PROCESS_TERMINATE, false, pid);
                        if (llHandle != null) if (Kernel32.TerminateProcess(llHandle, 1)) ret = 0;
                    }

                    Kernel32.CloseHandle(lHandle);
                    if (ret == 0) break;
                } else {
                    Kernel32.CloseHandle(new HANDLE(0));
                }
            }
        } catch (NativeException e) {
            log.warn(e.getMessage());
        } catch (IllegalAccessException e) {
            log.warn(e.getMessage());
        }
        return ret;
    }

    /**
     * 结束进程 默认忽略映像名称大小写
     *
     * @param moduleBaseName
     * @return
     */
    public int kill(String moduleBaseName) {
        return kill(moduleBaseName, true);
    }

    /**
     * 根据PID结束进程
     *
     * @param moduleBaseName
     * @return
     */
    public int kill(int pid) {
        try {
            log.debug("THe pid is: " + pid);
            HANDLE lHandle = Kernel32.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION
                    | Kernel32.PROCESS_VM_READ, false, pid);
            if (lHandle != null) {
                HANDLE llHandle = Kernel32.OpenProcess(Kernel32.PROCESS_TERMINATE, false, pid);
                if (llHandle != null) Kernel32.TerminateProcess(llHandle, 1);
                Kernel32.CloseHandle(lHandle);
            }
        } catch (NativeException e) {
            log.warn(e.getMessage());
        } catch (IllegalAccessException e) {
            log.warn(e.getMessage());
        }
        return 0;
    }
}
